#include <openssl/evp.h>
#include <openssl/sha.h>

#include "sha.h"

namespace Crypto
{

std::string sha256(const std::string& input)
{
    unsigned char hash[SHA256_DIGEST_LENGTH];
    const EVP_MD* md = EVP_sha256();
    EVP_MD_CTX* mdСtx = EVP_MD_CTX_new();
    EVP_DigestInit_ex(mdСtx, md, NULL);
    EVP_DigestUpdate(mdСtx, input.c_str(), input.length());
    EVP_DigestFinal_ex(mdСtx, hash, NULL);
    EVP_MD_CTX_free(mdСtx);

    std::string result;
    char hex[3];
    for (int i = 0; i < SHA256_DIGEST_LENGTH; i++)
    {
        sprintf(hex, "%02x", hash[i]);
        result += hex;
    }

    return result;
}

std::string sha512(const std::string& input)
{
    unsigned char hash[SHA512_DIGEST_LENGTH];
    const EVP_MD* md = EVP_sha512();
    EVP_MD_CTX* mdСtx = EVP_MD_CTX_new();
    EVP_DigestInit_ex(mdСtx, md, NULL);
    EVP_DigestUpdate(mdСtx, input.c_str(), input.length());
    EVP_DigestFinal_ex(mdСtx, hash, NULL);
    EVP_MD_CTX_free(mdСtx);

    std::string result;
    char hex[3];
    for (int i = 0; i < SHA512_DIGEST_LENGTH; i++)
    {
        sprintf(hex, "%02x", hash[i]);
        result += hex;
    }

    return result;
}

} // namespace Crypto
